home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************
-
- DOExchange.c
-
- It's a try to do the Exchange work within a dopus popup menu.
-
- Since nothing of the commodities.library is really documented,
- this source may be wrong. If you know more, you may change/add
- what is to do...
-
- SO BE WARNED... - THIS IS A HACK !!
- (even if it seems to be OK)
-
- Initial idea by Jens Weyer.
-
- *********************************************************************/
-
- #include "includes/DOExchange.h"
-
- /********************************************************************/
- // some prototypes
-
- ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
- register __a1 DOE_Data *dd );
-
- void __saveds New_Proc( void );
- void CleanUp( DOE_Data *dd, IPCData *ipc );
-
- BOOL OpenWin( DOE_Data *dd );
- void BorderDraw( DOE_Data *dd, BOOL invers );
-
- BOOL InitPopupMenu( DOE_Data *dd );
- APTR CreateSubMenu( DOE_Data *dd, ULONG from, ULONG to );
- void ClearPopupMenu( DOE_Data *dd );
- BOOL DoMenu( DOE_Data *dd );
-
- BOOL HandleWin( DOE_Data *dd );
- BOOL HandleCX( DOE_Data *dd );
- BOOL HandleNotify( DOE_Data *dd );
- BOOL HandleIPC( DOE_Data *dd );
-
- BOOL SendCxMsg( CX_OBJ *cxobj, ULONG type, struct MsgPort *reply_to );
-
- BOOL WriteConfig( DOE_Data *dd );
- BOOL ReadConfig( DOE_Data *dd );
-
- /********************************************************************/
- // it is surely useful to detach here
-
- void DOExchange( STRPTR args, struct Screen *screen, IPCData *ipc )
- {
- DOE_Data *dd;
- FuncArgs *fargs;
-
- if( !exchange )
- {
- if( (dd = AllocMemH(mempool, sizeof(DOE_Data))) )
- {
- dd->screen = screen;
- dd->a4 = getreg( REG_A4 );
- dd->module = (struct Library *) getreg( REG_A6 );
- dd->library = DOpusBase;
-
- IPC_Launch( 0,
- &exchange, // pointer to pointer to the IPC of the new process, for storing...
- "DOpus Exchange", // name of the new process
- (ULONG) New_Proc, // entrypoint of the new process
- 4096, // stack to use
- (ULONG) dd, // data to pass to the new process
- DOSBase ); // pointer to dos.library
-
- if( !exchange ) // if detaching failed...
- {
- FreeMemH( dd );
- return;
- }
- }
- }
-
- if( args )
- {
- if( (fargs = ParseArgs(FUNC0_TEMPLATE, args)) )
- {
- ULONG cmd = 0, counter;
- PassData *pd;
-
- for( counter = 0; counter < TEMPLATE_COUNT; counter++ )
- if( fargs->FA_Arguments[counter] )
- cmd |= 1 << counter;
-
- if( (pd = AllocVec(sizeof(PassData), MEMF_CLEAR)) )
- {
- pd->FrontPen = ARG_TC ? *(ULONG *) ARG_TC : NULL;
- pd->BackPen = ARG_BGC ? *(ULONG *) ARG_BGC : NULL;
- pd->name = ARG_NAME ? (STRPTR) ARG_NAME : NULL;
-
- IPC_Command( exchange,
- cmd,
- NULL,
- NULL,
- pd, // FreeVec the data automatically
- REPLY_NO_PORT );
- }
-
- DisposeArgs( fargs );
- }
- }
- }
-
- /********************************************************************/
-
- ULONG __asm __saveds New_Proc_Startup( register __a0 IPCData *ipc,
- register __a1 DOE_Data *dd )
- {
- struct Library *DOpusBase;
-
- putreg( REG_A4, dd->a4 );
- dd->ipc = ipc;
- DOpusBase = dd->library;
-
- // now follows our initialization
-
- dd->module->lib_OpenCnt++;
-
- // the default button text
- dd->itext.IText = DOpusGetString( locale, MSG_TEXT );
- dd->itext.FrontPen = 1;
-
- ReadConfig( dd );
-
- if( strlen(dd->name) )
- dd->itext.IText = dd->name;
-
- // install our notify
- if( !(dd->notify_port = CreateMsgPort()) ||
- !(dd->notify_handle = AddNotifyRequest(DN_OPUS_HIDE | DN_OPUS_SHOW | DN_OPUS_QUIT |
- DN_CLOSE_WORKBENCH | DN_OPEN_WORKBENCH | DN_RESET_WORKBENCH,
- NULL, dd->notify_port)) )
- return FALSE;
-
- // fill our newbroker structure
- dd->nb.nb_Version = NB_VERSION;
- dd->nb.nb_Name = DOpusGetString( locale, FUNC0_DESCRIPTION );
- dd->nb.nb_Title = dd->nb.nb_Name;
- dd->nb.nb_Descr = DOpusGetString( locale, MSG_CX_DESCR );
- dd->nb.nb_Unique = NBU_UNIQUE|NBU_NOTIFY;
- dd->nb.nb_Flags = COF_SHOW_HIDE;
-
- // create the broker
- if( !(dd->nb.nb_Port = CreateMsgPort()) ||
- !(dd->our_cxobj = CxBroker(&dd->nb, (LONG *) &dd->signals)) ||
- dd->signals ||
- !(dd->sender = CreateMsgPort()) )
- return FALSE;
-
- return TRUE; // all was successfully
- }
-
- void __saveds New_Proc( void )
- {
- DOE_Data *dd;
- IPCData *ipc;
- struct Library *DOpusBase;
-
- if( !(DOpusBase = (struct Library *) FindName(&((struct ExecBase *)*((ULONG *)4))->LibList, "dopus5.library")) )
- return;
-
- ipc = IPC_ProcStartup( (ULONG *) &dd, New_Proc_Startup );
- putreg( REG_A4, dd->a4 );
-
- if( !ipc )
- {
- if( dd )
- CleanUp( dd, dd->ipc );
-
- return;
- }
-
- // make our broker aktive
- ActivateCxObj( dd->our_cxobj, TRUE );
-
- // open the window (looks like a dopus button)
- if( OpenWin(dd) )
- {
- while( TRUE )
- {
- dd->signals = Wait( 1 << dd->sender->mp_SigBit | // reply port of our sended messages
- 1 << dd->nb.nb_Port->mp_SigBit |
- 1 << dd->notify_port->mp_SigBit |
- 1 << dd->ipc->command_port->mp_SigBit | // ipc messages
- (dd->win ? 1 << dd->win->UserPort->mp_SigBit : NULL) ); // IDCMP messages
-
- if( dd->signals & 1 << dd->sender->mp_SigBit ) // our message does return
- {
- while( (dd->fmsg = (FakeMsg *) GetMsg(dd->sender)) )
- FreeMemH( dd->fmsg ); // we have only to free the memory
- }
-
- dd->stop = FALSE;
-
- if( dd->signals & 1 << dd->nb.nb_Port->mp_SigBit )
- {
- if( HandleCX(dd) )
- break;
- }
-
- if( dd->signals & 1 << dd->notify_port->mp_SigBit )
- {
- if( HandleNotify(dd) )
- break;
- }
-
- if( dd->signals & 1 << dd->ipc->command_port->mp_SigBit )
- {
- if( HandleIPC(dd) )
- break;
- }
-
- if( dd->win && (dd->signals & 1 << dd->win->UserPort->mp_SigBit) )
- {
- if( HandleWin(dd) )
- break;
- }
- }
- }
-
- CleanUp( dd, exchange );
- exchange = NULL;
- }
-
- void CleanUp( DOE_Data *dd, IPCData *ipc )
- {
- if( dd->win )
- CloseWindow( dd->win );
-
- if( dd->notify_port )
- {
- if( dd->notify_handle )
- RemoveNotifyRequest( dd->notify_handle );
-
- while( !IsMsgPortEmpty( dd->notify_port) )
- ReplyFreeMsg( GetMsg(dd->notify_port) );
-
- DeleteMsgPort( dd->notify_port );
- }
-
- DeleteCxObjAll( dd->our_cxobj );
-
- if( dd->nb.nb_Port )
- {
- while( !IsMsgPortEmpty(dd->nb.nb_Port) )
- ReplyMsg( GetMsg(dd->nb.nb_Port) );
-
- DeleteMsgPort( dd->nb.nb_Port );
- }
-
- if( dd->sender )
- {
- while( !IsMsgPortEmpty(dd->sender) )
- FreeMemH( GetMsg(dd->sender) );
-
- DeleteMsgPort( dd->sender );
- }
-
- dd->module->lib_OpenCnt--;
-
- FreeMemH( dd );
-
- IPC_Free( ipc );
-
- }
-
- /********************************************************************/
-
- BOOL OpenWin( DOE_Data *dd )
- {
- // lock the screen
- if( (dd->screen = LockPubScreen(NULL)) )
- {
- if( (dd->win = OpenWindowTags( NULL,
- WA_Left, dd->ibox.Left,
- WA_Top, dd->ibox.Top,
- WA_Height, dd->screen->Font->ta_YSize + 4,
- WA_Width, IntuiTextLength( &dd->itext ) + 5,
-
- WA_Gadgets, &draggadget,
-
- WA_Flags, WFLG_BORDERLESS | WFLG_NEWLOOKMENUS |
- WFLG_SMART_REFRESH | WFLG_RMBTRAP,
-
- WA_IDCMP, IDCMP_MOUSEBUTTONS,
-
- WA_AutoAdjust, TRUE,
- WA_PubScreen, dd->screen,
- WA_ScreenTitle, (STRPTR) ~0,
- TAG_DONE)) )
- {
- // register our window, so it does get messages
- // even it is inactive
- SetWindowID( dd->win, &dd->id, 0x1400, 0 );
-
- BorderDraw( dd, FALSE );
- }
-
- UnlockPubScreen( NULL, dd->screen );
- }
-
- return (BOOL) dd->win;
- }
-
- void BorderDraw( DOE_Data *dd, BOOL invers )
- {
- // flood the port with supplied colour
- SetRast( dd->win->RPort, dd->itext.BackPen );
-
- // draw a border
- SetAPen( dd->win->RPort, invers ? 2 : 1 );
- Move( dd->win->RPort, 1, dd->win->Height - 1 );
- Draw( dd->win->RPort, dd->win->Width-1, dd->win->Height - 1 );
- Draw( dd->win->RPort, dd->win->Width-1, 1 );
-
- SetAPen( dd->win->RPort, invers ? 1 : 2 );
- Move( dd->win->RPort, 0, dd->win->Height - 1 );
- Draw( dd->win->RPort, 0, 0 );
- Draw( dd->win->RPort, dd->win->Width-1, 0 );
-
- // set values for the Rastport
- SetRPAttrs( dd->win->RPort,
- RPTAG_APen, dd->itext.FrontPen,
- RPTAG_BPen, dd->itext.BackPen,
- TAG_DONE );
-
- // print the button text
- Move( dd->win->RPort, 3, dd->win->RPort->Font->tf_Baseline + 2 );
- Text( dd->win->RPort, dd->itext.IText, strlen(dd->itext.IText) );
- }
-
- /********************************************************************/
- // popup menu work
-
- // do not be worry, most of this things is only needed to allow:
- // - unlimited count of entries with their needed submenu
- // - easier to do the cleanup
-
- BOOL InitPopupMenu( DOE_Data *dd )
- {
- dd->entry_count = 0;
-
- // init the lists we need
- NewList( (struct List *) &dd->popmenu.item_list );
- NewList( (struct List *) &dd->submenus );
-
- // open the popupmenu above our window
- dd->popmenu.flags = POPUPMF_ABOVE;
-
- // locale pointer, so we must not supply real strings - only ID's
- dd->popmenu.locale = locale;
-
- // since nothing is documented here, I have done what I think:
- // all brokers must be anywhere in a list and if we have one
- // node (our broker), we can access the whole list...
- dd->ptr_node = (struct Node *) dd->our_cxobj;
-
- // the objects does work with interrupts, it may a good idea
- // to protect the access to the list with Disable()
- Disable();
-
- // go to the head of the list
- do
- {
- dd->ptr_node = dd->ptr_node->ln_Pred;
- }
- while( dd->ptr_node->ln_Pred->ln_Pred );
-
- // now we can create our needed lists - we have here 2 + X (!)
- // first list - MinList with the names of the objects (needed by DoPopUpMenu)
- // second list - MinList, each node contain again a MinList (third list)
- // this list is only for easy handling for us
- // third (and X) list - MinList for submenu, it does also contain a pointer
- // to the cx_object
-
- do
- {
- // this counter is used to give each (main) menu item an ID.
- // since these items have all submenus, you may also give
- // all the same ID (dopus5.library does only pass them through)
- dd->entry_count++;
-
- // now it's time to create the menu entry...
- if( (dd->popitem = AllocMemH(mempool, sizeof(PopUpItem))) )
- {
- dd->popitem->item_name = dd->ptr_node->ln_Name;
- dd->popitem->id = dd->entry_count;
-
- // each item has a submenu
- if( (dd->popitem->data = CreateSubMenu(dd, MSG_ACTIVATE, MSG_REMOVE)) )
- dd->popitem->flags = POPUPF_SUB;
-
- // the next block is a kind of sorted adding of our nodes
- // since this are MinList's, it is not possible to use DOpus
- // list functions here...
-
- // at first we need a pointer to the first node
- dd->compare = (PopUpItem *) dd->popmenu.item_list.mlh_Head;
-
- if( IsListEmpty((struct List *) &dd->popmenu.item_list) ||
- Stricmp(dd->popitem->item_name, dd->compare->item_name) < 0 ) // or our new name is lower
- {
- AddHead( (struct List *) &dd->popmenu.item_list,
- (struct Node *) dd->popitem );
- }
- else
- {
- // walk through the list until a name is higher than our new name or
- // the list is no more entries
- while( dd->compare->node.mln_Succ->mln_Succ &&
- Stricmp(dd->popitem->item_name, ((PopUpItem *) dd->compare->node.mln_Succ)->item_name) > 0 )
- dd->compare = (PopUpItem *) dd->compare->node.mln_Succ;
-
- // insert the new node before (!) the higher name is coming
- // or even append it, if no higher entry does exist
- Insert( (struct List *) &dd->popmenu.item_list,
- (struct Node *) dd->popitem,
- (struct Node *) dd->compare );
- }
- }
- }
- while( (dd->ptr_node = dd->ptr_node->ln_Succ)->ln_Succ );
-
- // we have not all done now, but we must not access longer the object list,
- // so we can allow again all stuff
- Enable();
-
- // adding a barlabel
- if( (dd->popitem = AllocMemH(mempool, sizeof(PopUpItem))) )
- {
- dd->popitem->item_name = POPUP_BARLABEL;
- dd->popitem->id = 0;
-
- AddTail( (struct List *) &dd->popmenu.item_list,
- (struct Node *) dd->popitem );
- }
-
- // adding a item to snap the current settings
- if( (dd->popitem = AllocMemH(mempool, sizeof(PopUpItem))) )
- {
- dd->popitem->item_name = (STRPTR) MSG_SAVE_POS;
- dd->popitem->id = POPID_SAVE;
- dd->popitem->flags = POPUPF_LOCALE;
-
- AddTail( (struct List *) &dd->popmenu.item_list,
- (struct Node *) dd->popitem );
- }
-
- // and an item to allow to quit directly
- if( (dd->popitem = AllocMemH(mempool, sizeof(PopUpItem))) )
- {
- dd->popitem->item_name = (STRPTR) MSG_QUIT;
- dd->popitem->id = POPID_QUIT;
- dd->popitem->flags = POPUPF_LOCALE;
-
- AddTail( (struct List *) &dd->popmenu.item_list,
- (struct Node *) dd->popitem );
- }
-
- return TRUE;
- }
-
- // this routine is already prepared to be copied if you need it :)
- // you must change only small things then...
-
- APTR CreateSubMenu( DOE_Data *dd, ULONG from, ULONG to )
- {
- PopUpItem *popitem;
-
- if( (dd->submenu_node = AllocMemH(mempool, sizeof(SubMenu_Node))) )
- {
- // init the list
- NewList( (struct List *) &dd->submenu_node->submenu );
-
- // getting the items to show
- for( dd->a4 = from; dd->a4 <= to; dd->a4++ )
- {
- // allocate a node
- if( (popitem = AllocMemH(mempool, sizeof(PopUpItem))) )
- {
- // fill the node
- popitem->item_name = (STRPTR) dd->a4;
- popitem->flags = POPUPF_LOCALE;
- popitem->id = dd->a4;
- popitem->data = dd->ptr_node; // pointer to the CX_object
-
- switch( dd->a4 )
- {
- case MSG_ACTIVATE :
- popitem->flags |= POPUPF_CHECKIT;
-
- // now it is again result of hard work and
- // may be wrong... :)
- // check the current activation state
- //if( ((STRPTR) dd->ptr_node)[0x0E] & 1 << 1 )
- if( ((CX_OBJ *) dd->ptr_node)->flags & 1 << 1 )
- popitem->flags |= POPUPF_CHECKED;
-
- break;
-
- case MSG_APPEAR :
- case MSG_DISAPPEAR:
- // checking if this object has a GUI
- //if( !(((STRPTR) dd->ptr_node)[0x0E] & 1 << 2) )
- if( !(((CX_OBJ *) dd->ptr_node)->flags & 1 << 2) )
- popitem->flags |= POPUPF_DISABLED;
- }
-
- // add the popitem node to the submenu list
- AddTail( (struct List *) &dd->submenu_node->submenu,
- (struct Node *) popitem );
- }
- }
- // add the submenu list to the second list, so we can free it later all easily
- AddTail( (struct List *) &dd->submenus,
- (struct Node *) dd->submenu_node );
-
- return &dd->submenu_node->submenu;
- }
-
- return NULL;
- }
-
- // this routines should be clear for everyone...
- void ClearPopupMenu( DOE_Data *dd )
- {
- while( !IsListEmpty((struct List *) &dd->popmenu.item_list) )
- FreeMemH( RemHead((struct List *) &dd->popmenu.item_list) );
-
- while( !IsListEmpty((struct List *) &dd->submenus) )
- {
- dd->submenu_node = (SubMenu_Node *) RemHead((struct List *) &dd->submenus);
-
- while( !IsListEmpty((struct List *) &dd->submenu_node->submenu) )
- FreeMemH( RemHead((struct List *) &dd->submenu_node->submenu) );
-
- FreeMemH( dd->submenu_node );
- }
- }
-
- BOOL DoMenu( DOE_Data *dd )
- {
- // preparing the popupmenu
- if( InitPopupMenu(dd) )
- {
- // start the popupmenu
- if( DoPopUpMenu(dd->win, &dd->popmenu, &dd->popitem, MENUDOWN) != -1 )
- {
- // if the previous call does return, dd->popitem contains the user selection
- switch( dd->popitem->id )
- {
- case POPID_SAVE :
- WriteConfig( dd );
- break;
-
- case POPID_QUIT :
- dd->stop = TRUE;
- break;
-
- case MSG_ACTIVATE:
- case MSG_APPEAR:
- case MSG_DISAPPEAR:
- case MSG_REMOVE: // create a fake CxMsg (not documented...)
- // and send it to the choosed CxObj
-
- SendCxMsg( (CX_OBJ *) dd->popitem->data, // send it to...
- (dd->popitem->id == MSG_ACTIVATE ? (dd->popitem->flags & POPUPF_CHECKED ? CXCMD_ENABLE : CXCMD_DISABLE) : (dd->popitem->id - MSG_ACTIVATE)*2 + 17 ),
- dd->sender ); // use this port to reply to
-
- break;
- }
- }
- // free the menu
- ClearPopupMenu( dd );
- }
-
- return dd->stop;
- }
-
- /********************************************************************/
- // handling routines
-
- BOOL HandleWin( DOE_Data *dd )
- {
- while( !dd->stop && (dd->messages = GetMsg(dd->win->UserPort)) )
- {
- // since we are not interested in other messages, we use a simple "if"
- if( ((struct IntuiMessage *) dd->messages)->Class == IDCMP_MOUSEBUTTONS &&
- ((struct IntuiMessage *) dd->messages)->Code == MENUDOWN )
- //&&
- //((ULONG) WhichLayer(&dd->screen->LayerInfo, dd->screen->MouseX, dd->screen->MouseY)) == ((ULONG) dd->win->WLayer) )
- {
- // since we have no real gadget, the window must be activated
- // else the popup menu may be in some cases not selectable
- ActivateWindow( dd->win );
-
- // make our window "selected"
- BorderDraw( dd, TRUE );
-
- dd->stop = DoMenu( dd );
-
- // "unselect"
- BorderDraw( dd, FALSE );
-
- // deactivate our window again (will activate the previous
- // activated window, if available)
-
- if( dd->win->NextWindow )
- ActivateWindow( dd->win->NextWindow );
- else
- dd->win->Flags ^= WFLG_WINDOWACTIVE;
- }
- ReplyMsg( dd->messages );
- }
-
- return dd->stop;
- }
-
- BOOL HandleCX( DOE_Data *dd )
- {
- while( !dd->stop && (dd->messages = GetMsg(dd->nb.nb_Port)) )
- {
- // on this place we can use some variables for other work...
- dd->a4 = CxMsgType( (CxMsg *) dd->messages );
- dd->signals = CxMsgID((CxMsg *) dd->messages);
-
- // should be so fast as possible...
- ReplyMsg( dd->messages );
-
- if( dd->a4 == CXM_COMMAND )
- {
- switch( dd->signals )
- {
- case CXCMD_DISABLE: // since we are do not handle any
- // other things than our window, it
- // is a little bit useless to disable/
- // enable, but anyway we do it... :)
- ActivateCxObj( dd->our_cxobj, FALSE );
- break;
-
- case CXCMD_ENABLE:
- ActivateCxObj( dd->our_cxobj, TRUE );
- break;
-
- case CXCMD_APPEAR:
- if( !dd->win )
- {
- OpenWin( dd );
- }
- else
- WindowToFront( dd->win );
- break;
-
- case CXCMD_DISAPPEAR:
- if( dd->win )
- {
- // save our current position temporally
- dd->ibox.Left = dd->win->LeftEdge;
- dd->ibox.Top = dd->win->TopEdge;
-
- CloseWindow( dd->win );
- dd->win = NULL;
- }
- break;
-
- case CXCMD_KILL:
- dd->stop = TRUE;
- break;
-
-
- /* it seems this value needs a special flag in
- the newbroker structure and so no messages of
- this ID does arrive here...
-
- case CXCMD_LIST_CHG:
-
- break;
- */
- }
- }
- }
-
- return dd->stop;
- }
-
- BOOL HandleNotify( DOE_Data *dd )
- {
- while( !dd->stop && (dd->messages = GetMsg(dd->notify_port)) )
- {
- switch( ((DOpusNotify *) dd->messages)->dn_Type )
- {
- case DN_OPUS_QUIT :
- dd->stop = TRUE;
- break;
-
-
- case DN_CLOSE_WORKBENCH:
- case DN_OPUS_HIDE : // storing our current window state
- dd->flags = dd->win ? TRUE : FALSE;
-
- SendCxMsg( (CX_OBJ *) dd->our_cxobj,
- CXCMD_DISAPPEAR,
- dd->sender );
- break;
-
- case DN_OPEN_WORKBENCH:
- case DN_RESET_WORKBENCH:
- case DN_OPUS_SHOW :
- if( dd->flags )
- SendCxMsg( (CX_OBJ *) dd->our_cxobj,
- CXCMD_APPEAR,
- dd->sender );
- break;
- }
-
- ReplyFreeMsg( dd->messages );
- }
-
- return dd->stop;
- }
-
- BOOL HandleIPC( DOE_Data *dd )
- {
- while( !dd->stop && (dd->messages = GetMsg(dd->ipc->command_port)) )
- {
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_QUIT )
- {
- dd->stop = TRUE;
- }
- else
- {
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_SHOW )
- {
- SendCxMsg((CX_OBJ *) dd->our_cxobj, CXCMD_APPEAR, dd->sender );
- }
-
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_NAME )
- {
- // make a copy...
- strncpy( dd->name, ((PassData *) ((IPCMessage *) dd->messages)->data_free)->name, 11 )[11] = 0;
-
- // if the supplied name is empty, it does fallback to the buildin name
- dd->itext.IText = strlen(dd->name) ? dd->name : DOpusGetString( locale, MSG_TEXT );
- }
-
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_BGC )
- {
- dd->itext.BackPen = ((PassData *) ((IPCMessage *) dd->messages)->data_free)->BackPen;
- }
-
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_TC )
- {
- dd->itext.FrontPen = ((PassData *) ((IPCMessage *) dd->messages)->data_free)->FrontPen;
- }
-
- if( dd->win )
- {
- // save our current position temporally
- dd->ibox.Left = dd->win->LeftEdge;
- dd->ibox.Top = dd->win->TopEdge;
-
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_NAME )
- {
- // changing the name does require closing and reopening
- // of the window since the window size depends from the
- // name... (and font)
-
- CloseWindow( dd->win );
- OpenWin( dd );
- }
-
- if( ((IPCMessage *) dd->messages)->command & (IPCCMD_BGC | IPCCMD_TC) )
- {
- BorderDraw( dd, FALSE );
- }
-
- if( ((IPCMessage *) dd->messages)->command & IPCCMD_HIDE )
- {
- SendCxMsg((CX_OBJ *) dd->our_cxobj, CXCMD_DISAPPEAR, dd->sender );
- }
- }
- }
-
- IPC_Reply( dd->messages );
- }
-
- return dd->stop;
- }
-
- /********************************************************************/
-
- BOOL SendCxMsg( CX_OBJ *cxobj, ULONG type, struct MsgPort *reply_to )
- {
- FakeMsg *fmsg;
-
- // create a fake CxMsg (not documented..., size is 232 bytes)
- // and send it to the choosed CxObj
-
- if( (fmsg = AllocMemH(mempool, 232)) )
- {
- fmsg->msg.mn_Node.ln_Type = NT_MESSAGE;
- fmsg->msg.mn_Length = 232;
- fmsg->Code = CXM_COMMAND;
- fmsg->msg.mn_ReplyPort = reply_to;
- fmsg->ID = type;
-
- PutMsg( cxobj->cx_port, (struct Message *) fmsg );
-
- return TRUE;
- }
-
- return FALSE;
- }
-
- /********************************************************************/
- // saving/reading the config
- // normally I use for this an own file, but since here is only to
- // write some small values... :)
-
- // the following include is only needed to use some defines of it
- #include <libraries/iffparse.h>
-
- // now we are doing some ID's
- // each data block, which should be recognizeable must have an ID
- // (=header)
-
- #define DOE_ID MAKE_ID('D','O','E','X')
- #define LEFT_TOP MAKE_ID('L','E','T','E')
- #define COLOURS MAKE_ID('C','O','L','R')
- #define NEW_NAME MAKE_ID('N','A','M','E')
-
-
- BOOL WriteConfig( DOE_Data *dd )
- {
- APTR iffhandle;
- ULONG size;
-
- // open our config file for writing
- if( (iffhandle = IFFOpen(CONFIG_FILE, IFF_WRITE, DOE_ID)) )
- {
- // here you can see it is possible to write more than one value
- // with one step, they must only follow each other...
- IFFWriteChunk( iffhandle, &dd->win->LeftEdge, LEFT_TOP, sizeof(WORD) * 2 );
- IFFWriteChunk( iffhandle, &dd->itext.FrontPen, COLOURS, sizeof(UBYTE) * 2 );
-
- if( (size = strlen(dd->name)) )
- {
- // it's a nice idea to write the \0 of the string too,
- // it does save us work on reading the data
- IFFWriteChunk( iffhandle, dd->name, NEW_NAME, size + 1 );
- }
-
- IFFClose( iffhandle );
- return 0;
- };
-
- return 1;
- }
-
- // also simple to understand...
-
- BOOL ReadConfig( DOE_Data *dd )
- {
- APTR iffhandle;
- ULONG nextchunk;
-
- // open the config file for reading
- if( (iffhandle = IFFOpen(CONFIG_FILE, IFF_READ, DOE_ID)) )
- {
- // IFFNextChunk() does return the next ID (or NULL if there is none)
- // and so we can switch here
- while( (nextchunk = IFFNextChunk(iffhandle, 0)) )
- {
- switch( nextchunk )
- {
- case LEFT_TOP: IFFReadChunkBytes(iffhandle, &dd->ibox, sizeof(WORD) * 2 );
- break;
-
- case COLOURS : IFFReadChunkBytes(iffhandle, &dd->itext.FrontPen, sizeof(UBYTE) * 2 );
- break;
-
- case NEW_NAME: // if a string should be readed, it is needed to use the
- // string alone in a chunk or at least to have it at the
- // end of a structure - or -
- // if you do this not, you must always write the whole
- // structure
- // if you try to read an alone written string, you
- // must always set the size to read to the lenght of
- // you string buffer
-
- IFFReadChunkBytes(iffhandle, dd->name, 16 );
- break;
- };
- };
- IFFClose( iffhandle );
-
- return 0;
-
- };
- return 1;
- }
-